package com.qf.miaosha_service.service.impl;

import com.google.gson.Gson;
import com.qf.miaosha_service.dao.FlowersMapper;
import com.qf.miaosha_service.dao.SeckillMapper;
import com.qf.miaosha_service.dao.SeckillRecordMapper;
import com.qf.miaosha_service.entity.Flowers;
import com.qf.miaosha_service.entity.JsonResult;
import com.qf.miaosha_service.entity.Seckill;
import com.qf.miaosha_service.entity.SeckillRecord;
import com.qf.miaosha_service.service.SeckillService;
import com.qf.miaosha_service.util.RedisTool;
import com.qf.miaosha_service.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Scanner;
import java.util.UUID;

import static com.qf.miaosha_service.entity.JsonResult.createFailJsonResult;

@Service
@Transactional
public class SeckillServiceImpl implements SeckillService {

    private static final String SECKILL_KEY = "seckill";
    @Autowired
    private FlowersMapper flowersMapper;
    @Autowired
    private SeckillMapper seckillMapper;
    @Autowired
    private SeckillRecordMapper seckillRecordMapper;

    private Jedis jedis = RedisUtil.getJedis();
    private Gson gson = new Gson();

    /**
     * 根据花的id查询花的信息
     *
     * @param flowerId
     * @return
     */
    public Flowers findById(Long flowerId) {
        Flowers flowers = flowersMapper.selectByPrimaryKey(flowerId);
        return flowers;
    }

    /**
     * 根据库存大于0查询并添加到redis
     *
     * @return
     */
    @Override
    public boolean inredis() {
        Seckill seckill = seckillMapper.findBySun();
        if (seckill != null) {
            this.sevnRedis(seckill);
//            Gson gson = new Gson();
//            String pJson = gson.toJson(seckill);
//            jedis.set(SECKILL_KEY, pJson);
//                redisTemplate.opsForValue().set(SECKILL_KEY, pBytes);
            //用对象序列化流来将p对象序列化，然后把序列化之后的二进制数据写到ba流中
            return true;

        } else {
            return false;
        }
    }

    /**
     * 添加到redis
     * @param seckill
     */
    public void sevnRedis(Seckill seckill) {
        String pJson = gson.toJson(seckill);
        jedis.set(SECKILL_KEY, pJson);
    }

//    public void upBysum(Long flowerId) {
//        Example example = new Example(Seckill.class);
//        example.and().andEqualTo("flowerId",flowerId);
//        Seckill seckill = seckillMapper.selectOneByExample(flowerId);
//        Long sum = seckill.getSum();
//        sum--;
//        seckill.setSum(sum);
//        seckillMapper.updateByExampleSelective(seckill,example);
//    }

    /**
     * 秒杀结束后删除数据
     */
    public void deleteSeckill() {
//        Seckill seckill = (Seckill) redisTemplate.opsForValue().get(SECKILL_KEY);

//        Long id = seckill.getId();
//        seckillMapper.deleteByPrimaryKey(id);

        jedis.del(SECKILL_KEY);

    }

    /**
     * 根据用户查询是否秒杀成功过商品
     */
    public List<SeckillRecord> findByUserId(Long flowerId, Long userId) {
//        Long userId = 1L;

        Example example = new Example(SeckillRecord.class);
        if (flowerId != null) {
            Example example1 = new Example(Seckill.class);
            example1.and().andEqualTo("flowerId",flowerId);
            Seckill seckill = seckillMapper.selectOneByExample(example1);
            Long seckillId = seckill.getId();
            example.and().andEqualTo("seckillId", seckillId);
        }
        example.and().andEqualTo("userId", userId);

        List<SeckillRecord> seckillRecords = seckillRecordMapper.selectByExample(example);
        return seckillRecords;
    }
    /**
     * 秒杀开始
     *
     * @param flowerId
     * @return
     */
    @Override
    public JsonResult seckillBegin(Long flowerId, Long userId) {
//        Long userId = 1L;
        String requestId = UUID.randomUUID().toString().replaceAll("-", "");
        //加锁
        boolean lock = RedisTool.tryGetDistributedLock(jedis, SECKILL_KEY+userId, requestId, 3000);
        if (lock) {
            //加锁成功
//            Seckill seckill = (Seckill) redisTemplate.opsForValue().get(SECKILL_KEY);
            if (!jedis.exists(SECKILL_KEY)) {
                //key不存在
                //释放锁
                RedisTool.releaseDistributedLock(jedis, SECKILL_KEY, requestId);
                return createFailJsonResult("10004", "秒杀已结束");
            } else {
                //从redis中取出对象
                String seckillr = jedis.get(SECKILL_KEY);
                Seckill seckill = gson.fromJson(seckillr, Seckill.class);
                List<SeckillRecord> seckillRecords = this.findByUserId(flowerId, userId);
                if (seckillRecords.size() != 0) {
                    //用户已经参加过本次秒杀
                    //释放锁
                    RedisTool.releaseDistributedLock(jedis, SECKILL_KEY, requestId);
                    return createFailJsonResult("10001", "用户已经参与过该商品的秒杀");
                } else {
                    if (seckill.getSum() <= 0) {
                        //当库存为0时秒杀结束将数据库库存改为秒杀后的库存
                        seckill.setSum(seckill.getSum());
                        seckillMapper.updateByPrimaryKeySelective(seckill);
                        //释放锁
                        RedisTool.releaseDistributedLock(jedis, SECKILL_KEY, requestId);
                        //删除redis中的key
                        this.deleteSeckill();
                        return createFailJsonResult("10002", "商品已被秒杀完毕");
                    } else {
                        //开始秒杀
                        Long sum = seckill.getSum();
                        sum = sum - 1;
                        seckill.setSum(sum);
                        this.sevnRedis(seckill);
//                        redisTemplate.opsForValue().set(SECKILL_KEY, seckill);
                        //添加秒杀记录
                        SeckillRecord seckillRecord = new SeckillRecord();
                        Long seckillId = seckill.getId();
                        seckillRecord.setSeckillId(seckillId);
                        seckillRecord.setUserId(userId);
                        seckillRecordMapper.insert(seckillRecord);
                        //释放锁
                        RedisTool.releaseDistributedLock(jedis, SECKILL_KEY, requestId);
                        return createFailJsonResult("10000", "秒杀成功");
                    }
                }
            }
        } else {
            //加锁失败
            return createFailJsonResult("10003", "秒杀失败");
        }
    }
}
